home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
UTILITY1
/
BTNGO.ZIP
/
BTNGOC.ZIP
/
LONCH.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-28
|
32KB
|
750 lines
// DEBUG_SCREENS for message-box progress indicators
// FAKE_LAUNCHES for message boxes instead of actual launches
// SHOW_LAUNCHDATA for quick display just before prog launch -- works only if FAKE_LAUNCHES *not* specified
// CHANGE_DIR to change directory to entry's default before launch attempted
#include<windows.h>
#include<commdlg.h>
#include"wstring.hpp"
#include"itemdata.hpp"
#include"resource.h"
#include"ini.hpp"
#include<string.h>
#include<ctype.h>
#ifndef FAKE_LAUNCHES
#include<direct.h>
#endif
#define IDM_GETSTARTED 1
#define IDM_ABOUT 1001
#define IDM_HELP 1002
#define IDM_ONTOP 1003
#define IDM_MYSYSCOMMANDS 1010
#define BUTTON_WIDTH (icon_width+5)
IniFile ini;
GroupFile gf;
#ifdef DEBUG_SCREENS
WinMessageString screen;
#endif
WinMessageString errscreen;
const int SCRATCH=256;
unsigned int winver; // windows version
char scratch[SCRATCH+1];
static char WindowTitle[256];
static char szFile[256]; // filename for .GRP file
static HWND main_hwnd=NULL;
static HINSTANCE main_hinst=NULL;
static char AppTitle[]="ButtonGo";
static char AppClassName[]="ButtonGoDeurbrouckClass";
static char copyright[]=
"BTNGO.EXE 1.0\n"
"Program Launching Utility\n"
"Copyright ⌐ 1993 John Deurbrouck\n\n"
"First published in PC Magazine September 28, 1993\n";
static char helpstring[]=
"BTNGO conveniently displays the icons from any Program Manager group "
"and allows you to launch them with a single mouse click.\n\n"
"If started with a .GRP file specified on the command line, BTNGO can operate under "
"Windows 3.0 and later. Otherwise, BTNGO requires COMMDLG.DLL to run under 3.0.\n\n"
"See PC Magazine, September 28, 1993 (Vol. 12 No. 15) for more details. Support is also available "
"on ZiffNet. From Compuserve, GO ZNT:UTILFORUM.";
static char too_many_icons[]=
"The group you have loaded has too many icons to display, "
"so some of your icons may not be visible. "
"No damage has occurred, and you may use the icons you can see.\n\n"
"You can fix this by removing less-important items from the group, or by "
"creating another group file and moving some icons from this group "
"to the new one.";
static LPSTR command_line_pointer;
static HMENU gm=NULL; // system menu for main window
static HBITMAP hbmUp=NULL,hbmDown=NULL,hbmNow=NULL; // for painting the main window
static unsigned int max_index_added=0;
static int show_parameter; // for call to ShowWindow, parm passed into WinMain
static int actual_buttons=0; // number buttons on button bar
static int icon_height,icon_width,bitmap_width,bitmap_height;
static int mouse_down=0,mouse_button_number=-1,ok_to_launch; // used to drive mouse handling
static int should_save_position_data=0,got_position_data,best_ontop=1,best_x,best_y; // used for .INI file handling
void GetFilenameFromCmdLine(LPSTR cmdline,char *winpath,char *filename);
long FAR PASCAL __export MainWndProc(HWND,UINT,UINT,LONG);
int GetFileDataLoaded(LPSTR cmdline);
int CreateBitmaps(void);
int button_mouse_is_in(LONG lParam);
void restore_mouse_normalcy(void);
void get_right_bitmap(HDC hdc);
#ifdef FAKE_LAUNCHES
char *show_exe_data(int offset);
#else
void start_program(int offset);
#endif
int PASCAL WinMain(HINSTANCE hinstCurrent,HINSTANCE hinstPrevious,LPSTR lpszCmdLine,int nCmdShow){
if(!hinstPrevious){
WNDCLASS wc;
wc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
wc.lpfnWndProc=MainWndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hinstCurrent;
wc.hIcon=LoadIcon(hinstCurrent,MAKEINTRESOURCE(IDI_APPICON));
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=NULL;
wc.lpszMenuName=NULL;
wc.lpszClassName=AppClassName;
RegisterClass(&wc);
}
{
DWORD ver=GetVersion();
winver=LOBYTE(LOWORD(ver));
winver<<=8;
winver|=HIBYTE(LOWORD(ver));
}
command_line_pointer=lpszCmdLine;
main_hinst=hinstCurrent;
show_parameter=nCmdShow;
ini.set_instance(hinstCurrent);
main_hwnd=CreateWindow(AppClassName,AppTitle,
WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX,
CW_USEDEFAULT,CW_USEDEFAULT, // X,Y coords
CW_USEDEFAULT,CW_USEDEFAULT, // x,y extents
HWND_DESKTOP,NULL,hinstCurrent,NULL);
#ifdef DEBUG_SCREENS
screen.SetHwndParent(main_hwnd);
#endif
errscreen.SetHwndParent(main_hwnd);
MSG msg;
while(GetMessage(&msg,NULL,0,0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
static void GetFilenameFromCmdLine(LPSTR cmdline,char *winpath,char *filename){
LPSTR string_start;
int got_pathchars=0,got_goodchars=0,got_whitespace=0;
if(cmdline==NULL)return;
while(*cmdline){ // scan, find filename start, look for '\\' and ':'
if(isgraph(*cmdline)){
if(got_whitespace){
errscreen<<"Too many command line arguments";
errscreen.show();
return;
}
if(!got_goodchars){
got_goodchars=1;
string_start=cmdline;
}
if(*cmdline=='\\'||*cmdline==':')got_pathchars=1;
if(*cmdline=='*'||*cmdline=='?'){
errscreen<<"Can't use wildcards in command line arguments";
errscreen.show();
return;
}
}
else{
if(got_goodchars)got_whitespace=1;
}
cmdline++;
}
if(!got_goodchars)return; // no filename
if(!got_pathchars){ // insert Windows dir, normal place for .GRP
lstrcpy(filename,winpath);
cmdline=filename;
while(*cmdline)cmdline++;
if(cmdline[-1]!='\\'){*cmdline++='\\';*cmdline=0;}
lstrcat(filename,string_start);
}
else lstrcpy(filename,string_start);
// now scan off any whitespace at end of filename
cmdline=filename;
while(*cmdline)cmdline++;
cmdline--;
while(!isgraph(*cmdline))*cmdline--=0;
}
long FAR PASCAL __export MainWndProc(HWND hwnd,UINT message,UINT wParam,LONG lParam){
switch(message){
case WM_CREATE:
PostMessage(hwnd,WM_COMMAND,IDM_GETSTARTED,0L);
return 0;
case WM_COMMAND:
switch(wParam){
case IDM_GETSTARTED:
gm=GetSystemMenu(main_hwnd,FALSE);
DeleteMenu(gm,SC_SIZE,MF_BYCOMMAND);
DeleteMenu(gm,SC_MAXIMIZE,MF_BYCOMMAND);
AppendMenu(gm,MF_SEPARATOR,0,NULL);
if(winver>=0x30A)AppendMenu(gm,MF_STRING,IDM_ONTOP,"Always on Top");
AppendMenu(gm,MF_STRING,IDM_ABOUT,"About...");
AppendMenu(gm,MF_STRING,IDM_HELP,"Help...");
if(!GetFileDataLoaded(command_line_pointer)||
!gf.get_icon_dimensions(icon_height,icon_width)||
!CreateBitmaps()){
PostMessage(hwnd,WM_DESTROY,0,0L);
return 0;
}
if(gf.get_group_name()!=NULL){
wsprintf(WindowTitle,"%s - %s",(LPSTR)AppTitle,gf.get_group_name());
}
else lstrcpy(WindowTitle,AppTitle);
gf.done_with_bitmaps();
SetWindowText(hwnd,WindowTitle);
should_save_position_data=1;
got_position_data=ini.get_screen_numbers(szFile,best_x,best_y,best_ontop);
if(winver>=0x30A&&best_ontop)PostMessage(hwnd,WM_SYSCOMMAND,IDM_ONTOP,0L);
int window_width=GetSystemMetrics(SM_CXBORDER)*2+bitmap_width;
int window_height=GetSystemMetrics(SM_CYCAPTION)+bitmap_height+GetSystemMetrics(SM_CYBORDER);
/*
ok, someone changing from 1024x768 to 800x600 drivers might 'lose' the
window so let's be sure the window's at least partially onscreen.
if at least one pixel of the caption area is onscreen, the window
can be grabbed and moved, so let's check for that
*/
if(got_position_data)for(;;){
got_position_data=0; // so can break on errors
int capt_left=best_x+G